<?php

namespace common\service;

use common\libs\Curl;
use common\libs\ExchangeRate;
use common\model\sell66\SteamItem;
use common\model\sell66\SteamItemLog;
use common\model\sell66\SteamPriceLog;

class SteamItemService
{

    public static $instance = null;

    const STEAM_PRICE_API_URL = 'http://steamcommunity.com/market/priceoverview/?currency=23&appid=730&market_hash_name=';

    const STEAM_PRICE_LIST_API_URL = 'http://steamcommunity.com/market/search/render/?query=&search_descriptions=0&sort_column=popular&sort_dir=desc';

    const STEAM_ITEM_PRICE_LIST_API_URL = 'http://47.75.162.61/getSteamPrice';

    const STEAM_WANT_TO_BUY_PRICE_LIST_API_URL = 'http://47.75.162.61/getSteamWantToBuyPrice';

    const C5_PURCHASE_PRICE_LIST_API_URL = 'http://47.75.162.61/getC5PurchasePrice';

    const C5_PURCHASE_PRICE_MARKETHASHNAME_API_URL = 'http://47.75.162.61/getC5PurchasePriceByMarketHashName';

    public static $timeSection = [
        ['0', '9'],
        ['10', '18'],
    ];

    private function __construct()
    {

    }

    public static function getInstance()
    {
        if (self::$instance == null) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * 获取价格从steam官方
     * @return bool
     */
    public function getPriceBySteam()
    {
        $appId = 730;
        $count = $this->getSteamItemTotalNum($appId);
        $limit = 200;
        $max_loop = ceil($count / $limit);
        var_dump($count);
        $second = $this->getSecond();

        //添加数据
        $page = 1;
        for ($i = 1; $i <= $max_loop; $i++) {
            $this->getSteamItemInsertTable($appId, $second, $page, $limit);
            $page++;
        }
        return true;
    }

    /**
     * 获取steam总数
     * @param $appId
     * @return int
     */
    public function getSteamItemTotalNum($appId)
    {
        $param = [
            'appId' => $appId,
            'page' => 1,
            'limit' => 1,
            'time' => time(),
        ];

        $res = Curl::cURL(self::STEAM_ITEM_PRICE_LIST_API_URL . '?' . SteamPriceSignService::getInstance()->initParam($param));
        $res = json_decode($res, true);

        if($res['code'] == 1){
            return $res['result']['count'];
        }else{
            return 0;
        }
    }

    /**
     * 设置steam价格
     * @param $appId
     * @param int $page
     * @param int $limit
     */
    public function getSteamItemInsertTable($appId, $second, $page = 1, $limit = 100)
    {
        //获取数据
        $param = [
            'appId' => $appId,
            'page' => $page,
            'limit' => $limit,
            'time' => time(),
        ];
        $url = self::STEAM_ITEM_PRICE_LIST_API_URL . '?' . SteamPriceSignService::getInstance()->initParam($param);
        $result = Curl::cURL($url);
        $result = json_decode($result, true);
        $list = $result['result']['list'];
        $time = time();

        $steamPriceLog = new SteamPriceLog();

        if (!empty($list)) {
            echo $appId . '_' .  $page . PHP_EOL;
            foreach ($list as $key => $value) {
                $tmp_data = [];
                $tmp_data['market_hash_name'] = $value['market_hash_name'];
                $tmp_data['lowest_price'] = $value['lowest_price'] ? $value['lowest_price'] : 0;
                $tmp_data['median_price'] = $value['median_price'] ? $value['median_price'] : 0;
                $tmp_data['volume'] = $value['volume'] ? $value['volume'] : 0;
                $tmp_data['iteam_status'] = 1;
                $tmp_data['normal'] = 1;
                $tmp_data['second'] = $second;
                $tmp_data['created_time'] = $time;
                $tmp_data['updated_time'] = $time;
                $steamPriceLog->insert($tmp_data);
            }
        }
    }

    /**
     * 获取当前的批次
     * @return false|string
     */
    public function getSecond()
    {
        //获取批次
        $second = date('ymd');
        $nowH = date('H');
        $timeSection = self::$timeSection;
        $minNum = count($timeSection);
        foreach ($timeSection as $key => $val) {
            if ($val[0] < $nowH && $val[1] > $nowH) {
                $second = $second . $key;
            }
        }

        return $second > date('ymd') ? $second : $second . rand($minNum, 99);
    }

    /**
     * 通过Analyst获取价格
     * @param int $appId
     * @return array
     */
    public function updateCsgoPriceByAnalyst($appId = 730){
        $rsaResponse = Curl::cURL('https://www.xxskins.com/csgo.json');
        $result = json_decode($rsaResponse, true);
        $priceList = $result['results'];
        $res = SteamItem::updateCsgoPriceByAnalyst($priceList);
        return $res;
    }

    /**
     * 获取价格从steam官方
     * @return bool
     */
    public function getPubgPriceBySteam($appId = 578080)
    {
        $count = $this->getPubgPriceTotalNum($appId);
        $limit = 200;
        $max_loop = ceil($count / $limit);
        var_dump($count);
        $second = $this->getSecond();

        //添加数据
        $page = 1;
        for ($i = 1; $i <= $max_loop; $i++) {
            $this->getPubgPriceInsertTable($appId, $second, $page, $limit);
            $page++;
        }
        return true;
    }

    /**
     * 获取steam总数
     * @param $appId
     * @return int
     */
    public function getPubgPriceTotalNum($appId)
    {
        $param = [
            'appId' => $appId,
            'page' => 1,
            'limit' => 1,
            'time' => time(),
        ];

        $res = Curl::cURL(self::STEAM_ITEM_PRICE_LIST_API_URL . '?' . SteamPriceSignService::getInstance()->initParam($param));
        $res = json_decode($res, true);

        if($res['code'] == 1){
            return $res['result']['count'];
        }else{
            return 0;
        }
    }

    /**
     * 设置steam价格
     * @param $appId
     * @param int $page
     * @param int $limit
     */
    public function getPubgPriceInsertTable($appId, $second, $page = 1, $limit = 100)
    {
        //获取数据
        $param = [
            'appId' => $appId,
            'page' => $page,
            'limit' => $limit,
            'time' => time(),
        ];
        $url = self::STEAM_ITEM_PRICE_LIST_API_URL . '?' . SteamPriceSignService::getInstance()->initParam($param);
        $result = Curl::cURL($url);
        $result = json_decode($result, true);
        $list = $result['result']['list'];
        $time = time();

        $steamItem = new SteamItem();

        if (!empty($list)) {
            echo $page . PHP_EOL;
            foreach ($list as $key => $value) {
                $itemInfo = $steamItem->where('market_hash_name', '=', $value['market_hash_name'])->where('app_id', '=', $appId)->find();
                $tmp_data = [];
                $tmp_data['app_id'] = $appId;
                $tmp_data['market_hash_name'] = $value['market_hash_name'];
                $tmp_data['lowest_price'] = $value['lowest_price'] ? $value['lowest_price'] : 0;
                $tmp_data['median_price'] = $value['median_price'] ? $value['median_price'] : 0;
                $tmp_data['volume'] = $value['volume'] ? $value['volume'] : 0;
                $tmp_data['updated_time'] = $time;

                if (empty($itemInfo)) {
                    $tmp_data['second'] = 0;
                    $tmp_data['market_hash_name'] = $value['market_hash_name'];
                    $tmp_data['iteam_status'] = 2;      //1.可用 2.不可用
                    $tmp_data['normal'] = 3;      //1.正常 2.警告 3.上新 4.搁置 5.忽略
                    $tmp_data['created_time'] = $time;
                    $tmp_data['frist_create_time'] = $time;
                    $steamItem->insert($tmp_data);
                }else {
                    $steamItem->update($tmp_data, ['market_hash_name' => $value['market_hash_name'], 'app_id' => $appId]);
                }
            }
        }
    }

    /**
     * 获取价格从steam官方
     * @return bool
     */
    public function getSteamWantToBuyPrice($appId = 570)
    {
        $count = $this->getSteamWantToBuyPriceTotalNum($appId);
        $limit = 200;
        $max_loop = ceil($count / $limit);
        var_dump($count);
        $second = $this->getSecond();

        //添加数据
        $page = 1;
        for ($i = 1; $i <= $max_loop; $i++) {
            $this->getSteamWantToBuyPriceInsertTable($appId, $second, $page, $limit);
            $page++;
        }
        return true;
    }

    /**
     * 获取steam总数
     * @param $appId
     * @return int
     */
    public function getSteamWantToBuyPriceTotalNum($appId)
    {
        $param = [
            'appId' => $appId,
            'page' => 1,
            'limit' => 1,
            'time' => time(),
        ];

        $res = Curl::cURL(self::STEAM_WANT_TO_BUY_PRICE_LIST_API_URL . '?' . SteamPriceSignService::getInstance()->initParam($param));
        $res = json_decode($res, true);

        if($res['code'] == 1){
            return $res['result']['count'];
        }else{
            return 0;
        }
    }

    /**
     * 设置steam价格
     * @param $appId
     * @param int $page
     * @param int $limit
     */
    public function getSteamWantToBuyPriceInsertTable($appId, $second, $page = 1, $limit = 100)
    {
        //获取数据
        $param = [
            'appId' => $appId,
            'page' => $page,
            'limit' => $limit,
            'time' => time(),
        ];
        $url = self::STEAM_WANT_TO_BUY_PRICE_LIST_API_URL . '?' . SteamPriceSignService::getInstance()->initParam($param);
        $result = Curl::cURL($url);
        $result = json_decode($result, true);
        $list = $result['result']['list'];
        $time = time();

        $steamItem = new SteamItem();

        if (!empty($list)) {
            echo $page . PHP_EOL;
            foreach ($list as $key => $value) {
                $itemInfo = $steamItem->where('market_hash_name', '=', $value['market_hash_name'])->where('app_id', '=', $appId)->find();
                if($itemInfo){
                    $tmp_data = [];
                    $tmp_data['market_hash_name'] = $value['market_hash_name'];
                    $tmp_data['app_id'] = $appId;
                    $tmp_data['item_nameid'] = $value['item_nameid'];
                    $tmp_data['sell_price'] = $value['sell_price'];
                    $tmp_data['sell_num'] = $value['sell_num'];
                    $tmp_data['buy_price'] = $value['buy_price'];
                    $tmp_data['buy_num'] = $value['buy_num'];

                    if($appId == 578080 && $itemInfo['item_type'] == 1){
                        $tmp_data['incoming_price'] = $tmp_data['buy_price'];
                        $tmp_data['price'] = $tmp_data['incoming_price'] * ($itemInfo['step1_ratio'] / 100);
                        $tmp_data['second'] = $second;

                        SteamItemLog::create(['market_hash_name' => $value['market_hash_name'],
                            'second' => $second,
                            'app_id' =>$appId,
                            'source' => 2,
                            'cny_price' => $tmp_data['price'],
                            'created_time' => $time,
                            'updated_time' => $time]);
                    }

                    $tmp_data['create_at'] = $time;
                    $tmp_data['updated_time'] = $time;
                    $steamItem->update($tmp_data, ['market_hash_name' => $value['market_hash_name'], 'app_id' => $appId]);
                }
            }
        }
    }

    /**
     * 获取价格从steam官方
     * @return bool
     */
    public function getC5PurchasePrice($appId = 730)
    {
        $count = $this->getC5PurchasePriceTotalNum($appId);
        $limit = 200;
        $max_loop = ceil($count / $limit);
        var_dump($count);
        $second = $this->getSecond();

        //添加数据
        $page = 1;
        for ($i = 1; $i <= $max_loop; $i++) {
            $this->getC5PurchasePriceInsertTable($appId, $second, $page, $limit);
            $page++;
        }
        return true;
    }

    /**
     * 获取steam总数
     * @param $appId
     * @return int
     */
    public function getC5PurchasePriceTotalNum($appId)
    {
        $param = [
            'appId' => $appId,
            'page' => 1,
            'limit' => 1,
            'time' => time(),
        ];

        $res = Curl::cURL(self::C5_PURCHASE_PRICE_LIST_API_URL . '?' . SteamPriceSignService::getInstance()->initParam($param));
        $res = json_decode($res, true);

        if($res['code'] == 1){
            return $res['result']['count'];
        }else{
            return 0;
        }
    }

    /**
     * 设置steam价格
     * @param $appId
     * @param int $page
     * @param int $limit
     */
    public function getC5PurchasePriceInsertTable($appId, $second, $page = 1, $limit = 100)
    {
        //获取数据
        $param = [
            'appId' => $appId,
            'page' => $page,
            'limit' => $limit,
            'time' => time(),
        ];
        $url = self::C5_PURCHASE_PRICE_LIST_API_URL . '?' . SteamPriceSignService::getInstance()->initParam($param);
        $result = Curl::cURL($url);
        $result = json_decode($result, true);
        $list = $result['result']['list'];
        $time = time();

        $steamItem = new SteamItem();

        if (!empty($list)) {
            echo $page . PHP_EOL;
            foreach ($list as $key => $value) {
                $itemInfo = $steamItem->where('market_hash_name', '=', $value['market_hash_name'])->where('app_id', '=', $appId)->find();
                if($itemInfo){
                    $tmp_data = [];
                    $tmp_data['market_hash_name'] = $value['market_hash_name'];
                    $tmp_data['app_id'] = $appId;
                    $tmp_data['c5_want_to_buy_price'] = $value['purchase_price'];
                    $tmp_data['c5_want_to_buy_num'] = $value['num'];

                    if($itemInfo['item_type'] == 2){
                        $tmp_data['incoming_price'] = ($tmp_data['c5_want_to_buy_price'] <= ($itemInfo['lowest_price'] * 1)) ? $tmp_data['c5_want_to_buy_price'] : 0;
                        $tmp_data['price'] = $tmp_data['incoming_price'] * ($itemInfo['step1_ratio'] / 100);
                        $tmp_data['second'] = $second;
                        $tmp_data['note'] = $itemInfo['price'];
                        $tmp_data['normal'] = 1;
                        $tmp_data['collect'] = 1;
                        $tmp_data['iteam_status'] = 1;
                    }

                    $tmp_data['create_at'] = $time;
                    $tmp_data['updated_time'] = $time;
                    $steamItem->update($tmp_data, ['market_hash_name' => $value['market_hash_name'], 'app_id' => $appId]);
                }
            }
        }
    }

    /**
     * 获取价格从steam官方
     * @return bool
     */
    public function getC5PurchasePriceByMarketHashName($appId = 730)
    {
        $count = $this->getC5PurchasePriceTotalNumByMarketHashName($appId);
        $limit = 200;
        $max_loop = ceil($count / $limit);
        var_dump($count);
        $second = $this->getSecond();

        //添加数据
        $page = 1;
        for ($i = 1; $i <= $max_loop; $i++) {
            $this->getC5PurchasePriceInsertTableByMarketHashName($appId, $second, $page, $limit);
            $page++;
        }
        return true;
    }

    /**
     * 获取steam总数
     * @param $appId
     * @return int
     */
    public function getC5PurchasePriceTotalNumByMarketHashName($appId)
    {
        $steamItem = new SteamItem();
        return $steamItem->where('app_id', '=', $appId)->where('item_type', '=', 2)->count();
    }

    public function getC5PurchasePriceInsertTableByMarketHashName($appId, $second, $page = 1, $limit = 100)
    {
        $time = time();
        $steamItem = new SteamItem();
        $list = $steamItem->where('app_id', '=', $appId)->where('item_type', '=', 2)->limit(($page - 1) * $limit, $limit)->select();

        if (!empty($list)) {
            echo $page . PHP_EOL;
            foreach ($list as $key => $value) {
                //获取数据
                $param = [
                    'appId' => $appId,
                    'marketHashName' => $value['market_hash_name'],
                    'time' => time(),
                ];
                $url = self::C5_PURCHASE_PRICE_MARKETHASHNAME_API_URL . '?' . SteamPriceSignService::getInstance()->initParam($param);
                $result = Curl::cURL($url);
                $result = json_decode($result, true);
                $priceInfo = $result['result'];

                $tmp_data = [];
                if($priceInfo){
                    $tmp_data['c5_want_to_buy_price'] = $priceInfo['purchase_price'];
                    $tmp_data['c5_want_to_buy_num'] = $priceInfo['num'];
                    $tmp_data['incoming_price'] = ($tmp_data['c5_want_to_buy_price'] <= ($value['lowest_price'] * 1)) ? $tmp_data['c5_want_to_buy_price'] : 0;
                    $tmp_data['price'] = $tmp_data['incoming_price'] * ($value['step1_ratio'] / 100);
                }else{
                    $tmp_data['c5_want_to_buy_price'] = 0;
                    $tmp_data['c5_want_to_buy_num'] = 0;
                    $tmp_data['incoming_price'] = 0;
                    $tmp_data['price'] = 0;
                }

                SteamItemLog::create(['market_hash_name' => $value['market_hash_name'],
                    'second' => $second,
                    'app_id' =>$appId,
                    'source' => 2,
                    'cny_price' => $tmp_data['price'],
                    'created_time' => $time,
                    'updated_time' => $time]);

                $tmp_data['second'] = $second;
                $tmp_data['note'] = $value['price'];
                $tmp_data['normal'] = 1;
                $tmp_data['collect'] = 1;
                $tmp_data['iteam_status'] = 1;
                $tmp_data['create_at'] = $time;
                $tmp_data['updated_time'] = $time;
                $steamItem->update($tmp_data, ['market_hash_name' => $value['market_hash_name'], 'app_id' => $appId]);
            }
        }
    }

    /**
     * 开启多个进程执行任务
     * @param $model
     * @param $command
     * @param $data
     * @param int $maxNumber
     * @return bool
     */
    public function forkCommand($model, $command, $data, $maxNumber = 4)
    {
        $forkedNumber = 0;
        $pids = [];

        $dataChunk = array_chunk($data, ceil(count($data) / $maxNumber), true);
        unset($steamItemList);

        for ($i = 0; $i < $maxNumber; $i++) {
            $pid = pcntl_fork();
            if ($pid < 0) {
                return false;
            } elseif ($pid == 0) {
                echo $i . "start \n";
                $model->$command($dataChunk[$i]);
                echo $i . "exit \n";
                exit(0);
            } else {
                $pids[] = $pid;
                $forkedNumber++;
            }
        }

        if ($forkedNumber >= $maxNumber) {
            while (count($pids) > 0) {
                foreach ($pids as $key => $pid) {
                    $res = pcntl_waitpid($pid, $status, WNOHANG);

                    if ($res == -1 || $res > 0) {
                        unset($pids[$key]);
                    }
                }

                usleep(100);
            }
        }

        return true;
    }
}